﻿/*
 *Author: Jeff Liu 
 *
 *Under MIT License
 *jebberwocky@gmail.com
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Citiport.Util;
using Citiport.Util.Google.Language;

using CtpGglTranslate.Interface;
using CtpGglTranslate.Event;

namespace CtpGglTranslate.Ggl
{
    public class Translator
    {
        /// <summary>
        /// Class for translated result
        /// </summary>
        public class TranslatedPost
        {
            public String text { set; get; }

            public bool isOriginal { set; get; }

            public string langcode { set; get; }

            public bool isAccurary { set; get; }

            public TranslatedPost(String text, bool isOriginal, String langcode, bool accurary)
            {
                this.text = HtmlUtil.FixGoogleUrlEncode(text);
                this.isOriginal = isOriginal;
                this.langcode = langcode;
                this.isAccurary = accurary;
            }
        }

        public static readonly String GoogleLangSeparator = "|";

        public static Translator.TranslatedPost EmptyPost = new TranslatedPost("", true, "", true);

        public event GglTranslateEventHandler OnTranslatedHandler;

        public ICacheManger CacheManager { set; get; }

        public IKeyGen KeyGen { set; get; }

        [Obsolete("using OnTranslatedHandler")] 
        public IWriter Writer { set; get; }

        /// <summary>
        /// Is google detect result reliable
        /// </summary>
        /// <param name="dl">detected result</param>
        /// <returns>true whether the result is reliable</returns>
        private bool isResultReliable(JSON.DetectedLang dl)
        {
            /*
             * More logic
             */
            if (dl == null)
                return false;
            return dl.responseData.isReliable;
        }

        /// <summary>
        /// Translate by Google Service
        /// </summary>
        /// <param name="input">input text</param>
        /// <param name="defaultLang">see LanguageConst</param>
        /// <param name="to_lang">see LanguageConst<</param>
        /// <returns>TranslatedPost </returns>
        public  TranslatedPost GetTranslatedPost(String input, String defaultLang, String to_lang)
        {
            if (string.IsNullOrEmpty(input))
                return EmptyPost;

            //Find detect language code, if not find use user default
            String detectLang = null;
            JSON.DetectedLang dl = null;
            try
            {
                String json = GoogleLangAPI.DetectLang(input);
                dl = JSON.parseDetectedLang(json);
                detectLang = dl.responseData.language; //TODO: use google detect
            }
            catch (GoogleLanguageException gle)
            {
               //work on exception 
                throw gle;
            }
            if (detectLang != null && isResultReliable(dl))
            {
                detectLang = detectLang.ToLower().Trim();
            }
            else
            {
                detectLang = defaultLang.ToLower().Trim();
            }
            //Translate post
            String resultTxt = null;
            String key = null;
            if (this.KeyGen != null && this.CacheManager != null)
            {
                key = KeyGen.getKey(input+defaultLang + GoogleLangSeparator + to_lang);
                resultTxt = (String)CacheManager.get(key);
            }
            if (string.IsNullOrEmpty(resultTxt))
            {
                String rjson = GoogleLangAPI.TranslateText(input, defaultLang + GoogleLangSeparator + to_lang);
                JSON.TranslatedText tt = JSON.parseTranslatedText(rjson);
                resultTxt = tt.responseData.translatedText;
                if (this.KeyGen != null && this.CacheManager != null)
                    CacheManager.put(key, resultTxt);
                if (tt.responseStatus == 400)
                {
                    throw new WebRequstBaseException();
                }
            }

            TranslatedPost tlp = new TranslatedPost(resultTxt, false, to_lang , false);
            if(this.OnTranslatedHandler != null)
                this.OnTranslatedHandler(this, new GglTranslateEventAgrs(tlp));
            if (this.Writer != null)
            {
                this.Writer.write(tlp);
            }
            return tlp; 
        }
    }
}
